]> git.mxchange.org Git - addressbook-lib.git/blob - Addressbook/src/org/mxchange/addressbook/client/gui/AddressbookFrame.java
Introduced updateStatus() + shutdownApplication()
[addressbook-lib.git] / Addressbook / src / org / mxchange / addressbook / client / gui / AddressbookFrame.java
1 /*
2  * Copyright (C) 2015 Roland Haeder
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 package org.mxchange.addressbook.client.gui;
18
19 import java.awt.BorderLayout;
20 import java.awt.event.ActionEvent;
21 import java.awt.event.ActionListener;
22 import java.awt.event.WindowAdapter;
23 import java.awt.event.WindowEvent;
24 import java.text.MessageFormat;
25 import javax.swing.BorderFactory;
26 import javax.swing.BoxLayout;
27 import javax.swing.JFrame;
28 import javax.swing.JLabel;
29 import javax.swing.JMenu;
30 import javax.swing.JMenuBar;
31 import javax.swing.JMenuItem;
32 import javax.swing.JPanel;
33 import org.mxchange.addressbook.BaseFrameworkSystem;
34 import org.mxchange.addressbook.application.AddressbookApplication;
35 import org.mxchange.addressbook.client.Client;
36 import org.mxchange.addressbook.exceptions.FrameAlreadyInitializedException;
37
38 /**
39  *
40  * @author Roland Haeder
41  */
42 public class AddressbookFrame extends BaseFrameworkSystem implements ClientFrame {
43
44     /**
45      * Own instance
46      */
47     private static ClientFrame self;
48
49     /**
50      * Singelton getter for this frame instance.
51      *
52      * @param client Client instance
53      * @return Returns a singelton instance of this frame
54      */
55     public static final ClientFrame getSelfInstance (final Client client) {
56         // Is it set?
57         if (!(self instanceof ClientFrame)) {
58             // Create new instance
59             self = new AddressbookFrame(client);
60         }
61         
62         // Return instance
63         return self;
64     }
65     /**
66      * Frame instance for "add own data"
67      */
68     private JMenuItem addOwnItem;
69
70     /**
71      * Frame instance for "edit own data"
72      */
73     private JMenuItem editOwnItem;
74
75     /**
76      * Frame instance
77      */
78     private final JFrame frame;
79
80     /**
81      * Whether this frame has been initialized
82      */
83     private boolean isInitialized;
84
85     /**
86      * Status label needs to be updated
87      */
88     private JLabel statusLabel;
89
90     /**
91      * Creates an instance of this frame with a client instance
92      * 
93      * @param client
94      */
95     private AddressbookFrame (final Client client) {
96         // Debug line
97         this.getLogger().trace(MessageFormat.format("client={0}: CALLED!", client));
98
99         // Set frame instance
100         this.frame = new JFrame(AddressbookApplication.printableTitle());
101
102         // Set client here
103         this.setClient(client);
104     }
105
106     /**
107      * Shutdown this frame
108      */
109     @Override
110     public void doShutdown () {
111         // First only show shutdown status
112         this.statusLabel.setText(this.getBundle().getString("AddressbookFrame.statusLabel.shutdown.text"));
113     }
114
115     /**
116      * Setups the frame, do not set isInitialized here
117      * 
118      * @param client Client instance
119      */
120     @Override
121     public void setupFrame (final Client client) {
122         // Debug line
123         this.getLogger().trace(MessageFormat.format("client={0}: CALLED!", client));
124
125         // Has the user entered own data?
126         if (this.getClient().getContactManager().isOwnContactAdded()) {
127             // Debug message
128             this.getLogger().debug("Disabling menus: isOwnContactAdded()=false");
129
130             // Not entered yet, so disable "add" menu
131             this.addOwnItem.setEnabled(false);
132         } else {
133             // Disable "edit"
134             this.editOwnItem.setEnabled(false);
135         }
136
137         // Make the frame visible
138         this.frame.setVisible(true);
139
140         // All done here
141         this.updateStatus("done");
142     }
143
144     /**
145      * Initalizes this frame. Having initComponents() exposed (publicly
146      * accessible) means that any other object can initialize components which
147      * you may not want.
148      * 
149      * @throws org.mxchange.addressbook.exceptions.FrameAlreadyInitializedException If this method has been called twice
150      */
151     @Override
152     public void init () throws FrameAlreadyInitializedException {
153         // Debug line
154         this.getLogger().trace("CALLED!");
155
156         // Has this frame been initialized?
157         if (this.isInitialized()) {
158             // Throw exception
159             throw new FrameAlreadyInitializedException();
160         }
161
162         // Init components
163         this.initComponents();
164
165         // Set flag
166         this.isInitialized = true;
167     }
168
169     /**
170      * Returns field isInitialized. This flag indicates whether this frame has been initialized or not.
171      * 
172      * @return Field isInitialized
173      */
174     @Override
175     public final boolean isInitialized () {
176         return this.isInitialized;
177     }
178
179     /**
180      * Shuts down the application.
181      */
182     @Override
183     public void shutdownApplication () {
184         // To do this, the frame must be initialized
185         if (!this.isInitialized()) {
186             // Not initalized, so bad call
187             this.getLogger().fatal("Bad call of shutdownApplication(). Please report this.");
188             return;
189         }
190         this.getClient().getApplication().doShutdown();
191     }
192
193     /**
194      * Initialize components
195      */
196     private void initComponents () {
197         // Debug line
198         this.getLogger().trace("CALLED!");
199
200         // Set default close operation
201         this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
202
203         // Register shutdown listener
204         this.frame.addWindowListener(new WindowAdapter() {
205             /**
206              * Invoked when a window has been closed.
207              */
208             @Override
209             public void windowClosed(final WindowEvent e) {
210                 // Shutdown application cleanly
211                 self.shutdownApplication();
212             }
213
214             /**
215              * Invoked when a window is in the process of being closed.
216              * The close operation can be overridden at this point.
217              */
218             @Override
219             public void windowClosing(final WindowEvent e) {
220                 // Also shutdown cleanly here
221                 self.shutdownApplication();
222             }
223         });
224
225         // Setup layout manager
226         this.frame.setLayout(new BorderLayout(2, 2));
227
228         // Set window size
229         this.frame.setSize(700, 400);
230
231         // Center window in middle of screen, instead of top-left corner
232         this.frame.setLocationRelativeTo(null);
233
234         // Init menu system
235         initMenuSystem();
236
237         // Init status panel
238         initStatusPanel();
239     }
240
241     /**
242      * Initializes the menu system
243      */
244     private void initMenuSystem () {
245         // Init menu bar, menu and item instances
246         JMenuBar menuBar = new JMenuBar();
247         JMenu menu;
248         JMenuItem item;
249
250         // Init some menus:
251         // 1) File menu
252         menu = new JMenu(this.getBundle().getString("AddressbookFrame.menu.file.text"));
253
254         // Add menu items:
255         // 1.x) Exit program (should be last)
256         item = new JMenuItem(this.getBundle().getString("AddressbookFrame.menuItem.exitProgram.text"));
257         item.setToolTipText(this.getBundle().getString("AddressbookFrame.menuItem.exitProgram.toolTipText"));
258
259         // Add listener to exit menu
260         item.addActionListener(new ActionListener() {
261             /**
262              * If the user has performed this action
263              *
264              * @param e An instance of an ActionEvent class
265              */
266             @Override
267             public void actionPerformed (final ActionEvent e) {
268                 self.shutdownApplication();
269             }
270         });
271
272         // Add item -> menu
273         menu.add(item);
274
275         // Add menu -> menu bar
276         menuBar.add(menu);
277
278         // Init some menus:
279         // 2) Addressbook menu
280         menu = new JMenu(this.getBundle().getString("AddressbookFrame.menu.addressbook.text"));
281
282         // 2.1) Add own data
283         this.addOwnItem = new JMenuItem(this.getBundle().getString("AddressbookFrame.menuItem.addOwnData.text"));
284         this.addOwnItem.setToolTipText(this.getBundle().getString("AddressbookFrame.menuItem.addOwnData.toolTipText"));
285
286         // Add listener to exit menu
287         this.addOwnItem.addActionListener(new ActionListener() {
288             /**
289              * If the user has performed this action
290              *
291              * @param e An instance of an ActionEvent class
292              */
293             @Override
294             public void actionPerformed (final ActionEvent e) {
295                 self.getClient().getContactManager().doEnterOwnData();
296             }
297         });
298
299         // Add item -> menu
300         menu.add(this.addOwnItem);
301
302         // 2.2) Edit own data
303         this.editOwnItem = new JMenuItem(this.getBundle().getString("AddressbookFrame.menuItem.editOwnData.text"));
304         this.editOwnItem.setToolTipText(this.getBundle().getString("AddressbookFrame.menuItem.editOwnData.toolTipText"));
305
306         // Add listener to exit menu
307         this.editOwnItem.addActionListener(new ActionListener() {
308             /**
309              * If the user has performed this action
310              *
311              * @param e An instance of an ActionEvent class
312              */
313             @Override
314             public void actionPerformed (final ActionEvent e) {
315                 self.getClient().getContactManager().doChangeOwnData();
316             }
317         });
318
319         // Add item -> menu
320         menu.add(this.editOwnItem);
321
322         // Add menu -> menu bar
323         menuBar.add(menu);
324
325         // Add menu bar -> frame
326         this.frame.add(menuBar, BorderLayout.NORTH);
327     }
328
329     /**
330      * Initializes status panel
331      */
332     private void initStatusPanel () {
333         // Init status label (which needs to be updated
334         this.statusLabel = new JLabel();
335         this.updateStatus("initializing");
336
337         // Init status bar in south
338         JPanel panel = new JPanel();
339         panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
340         panel.add(this.statusLabel);
341         panel.setBorder(BorderFactory.createEtchedBorder());
342         
343         // Add panel to frame
344         this.frame.add(panel, BorderLayout.SOUTH);
345     }
346
347     /**
348      * Updates status to given type
349      * 
350      * @param type Status type
351      */
352     private void updateStatus (final String type) {
353         // Set status message
354         this.statusLabel.setText(this.getBundle().getString("AddressbookFrame.statusLabel." + type + ".text"));
355     }
356 }