2 * Copyright (C) 2015 Roland Haeder
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.
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.
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/>.
17 package org.mxchange.addressbook.client.gui;
19 import java.awt.BorderLayout;
20 import java.awt.event.ActionEvent;
21 import java.awt.event.ActionListener;
22 import java.awt.event.MouseAdapter;
23 import java.awt.event.MouseEvent;
24 import java.awt.event.WindowAdapter;
25 import java.awt.event.WindowEvent;
26 import java.text.MessageFormat;
27 import javax.swing.BorderFactory;
28 import javax.swing.BoxLayout;
29 import javax.swing.JFrame;
30 import javax.swing.JLabel;
31 import javax.swing.JMenu;
32 import javax.swing.JMenuBar;
33 import javax.swing.JMenuItem;
34 import javax.swing.JPanel;
35 import javax.swing.JTable;
36 import javax.swing.table.TableModel;
37 import org.mxchange.addressbook.BaseFrameworkSystem;
38 import org.mxchange.addressbook.application.AddressbookApplication;
39 import org.mxchange.addressbook.client.Client;
40 import org.mxchange.addressbook.exceptions.FrameAlreadyInitializedException;
41 import org.mxchange.addressbook.model.contact.ContactTableModel;
45 * @author Roland Haeder
47 public class AddressbookFrame extends BaseFrameworkSystem implements ClientFrame {
52 private static ClientFrame self;
55 * Singelton getter for this frame instance.
57 * @param client Client instance
58 * @return Returns a singelton instance of this frame
60 public static final ClientFrame getSelfInstance (final Client client) {
62 if (!(self instanceof ClientFrame)) {
63 // Create new instance
64 self = new AddressbookFrame(client);
71 * Frame instance for "add own data"
73 private JMenuItem addOwnItem;
76 * Instance to table model
78 private TableModel dataModel;
83 private JTable dataTable;
86 * Frame instance for "edit own data"
88 private JMenuItem editOwnItem;
93 private final JFrame frame;
96 * Whether this frame has been initialized
98 private boolean isInitialized;
101 * Status label needs to be updated
103 private JLabel statusLabel;
106 * Creates an instance of this frame with a client instance
110 private AddressbookFrame (final Client client) {
112 this.getLogger().trace(MessageFormat.format("client={0}: CALLED!", client));
114 // Set frame instance
115 this.frame = new JFrame(AddressbookApplication.printableTitle());
118 this.setClient(client);
122 * Shutdown this frame
125 public void doShutdown () {
126 // First only show shutdown status
127 this.updateStatus("shutdown");
131 * Setups the frame, do not set isInitialized here
133 * @param client Client instance
136 public void setupFrame (final Client client) {
138 this.getLogger().trace(MessageFormat.format("client={0}: CALLED!", client));
140 // Has the user entered own data?
141 if (this.getClient().getContactManager().isOwnContactAdded()) {
143 this.getLogger().debug("Disabling menus: isOwnContactAdded()=false");
145 // Not entered yet, so disable "add" menu
146 this.addOwnItem.setEnabled(false);
149 this.editOwnItem.setEnabled(false);
152 // Make the frame visible
153 this.frame.setVisible(true);
156 this.updateStatus("done");
160 * Initalizes this frame. Having initComponents() exposed (publicly
161 * accessible) means that any other object can initialize components which
165 * org.mxchange.addressbook.exceptions.FrameAlreadyInitializedException If
166 * this method has been called twice
169 public void init () throws FrameAlreadyInitializedException {
171 this.getLogger().trace("CALLED!");
173 // Has this frame been initialized?
174 if (this.isInitialized()) {
176 throw new FrameAlreadyInitializedException();
180 this.initComponents();
183 this.isInitialized = true;
187 * Returns field isInitialized. This flag indicates whether this frame has
188 * been initialized or not.
190 * @return Field isInitialized
193 public final boolean isInitialized () {
194 return this.isInitialized;
198 * Shuts down the application.
201 public void shutdownApplication () {
202 // To do this, the frame must be initialized
203 if (!this.isInitialized()) {
204 // Not initalized, so bad call
205 this.getLogger().fatal("Bad call of shutdownApplication(). Please report this.");
208 this.getClient().getApplication().doShutdown();
212 * Initialize components
214 private void initComponents () {
216 this.getLogger().trace("CALLED!");
218 // Set default close operation
219 this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
221 // Register shutdown listener
222 this.frame.addWindowListener(new WindowAdapter() {
224 * Invoked when a window has been closed.
227 public void windowClosed (final WindowEvent e) {
228 // Shutdown application cleanly
229 self.shutdownApplication();
233 * Invoked when a window is in the process of being closed. The
234 * close operation can be overridden at this point.
237 public void windowClosing (final WindowEvent e) {
238 // Also shutdown cleanly here
239 self.shutdownApplication();
243 // Setup layout manager
244 this.frame.setLayout(new BorderLayout(2, 2));
247 this.frame.setSize(700, 400);
249 // Center window in middle of screen, instead of top-left corner
250 this.frame.setLocationRelativeTo(null);
263 * Initializes the menu system
265 private void initMenuSystem () {
266 // Init menu bar, menu and item instances
267 JMenuBar menuBar = new JMenuBar();
273 menu = new JMenu(this.getBundle().getString("AddressbookFrame.menu.file.text"));
276 // 1.x) Exit program (should be last)
277 item = new JMenuItem(this.getBundle().getString("AddressbookFrame.menuItem.exitProgram.text"));
278 item.setToolTipText(this.getBundle().getString("AddressbookFrame.menuItem.exitProgram.toolTipText"));
280 // Add listener to exit menu
281 item.addActionListener(new ActionListener() {
283 * If the user has performed this action
285 * @param e An instance of an ActionEvent class
288 public void actionPerformed (final ActionEvent e) {
289 self.shutdownApplication();
296 // Add menu -> menu bar
300 // 2) Addressbook menu
301 menu = new JMenu(this.getBundle().getString("AddressbookFrame.menu.addressbook.text"));
304 this.addOwnItem = new JMenuItem(this.getBundle().getString("AddressbookFrame.menuItem.addOwnData.text"));
305 this.addOwnItem.setToolTipText(this.getBundle().getString("AddressbookFrame.menuItem.addOwnData.toolTipText"));
307 // Add listener to exit menu
308 this.addOwnItem.addActionListener(new ActionListener() {
310 * If the user has performed this action
312 * @param e An instance of an ActionEvent class
315 public void actionPerformed (final ActionEvent e) {
316 self.getClient().getContactManager().doEnterOwnData();
321 menu.add(this.addOwnItem);
323 // 2.2) Edit own data
324 this.editOwnItem = new JMenuItem(this.getBundle().getString("AddressbookFrame.menuItem.editOwnData.text"));
325 this.editOwnItem.setToolTipText(this.getBundle().getString("AddressbookFrame.menuItem.editOwnData.toolTipText"));
327 // Add listener to exit menu
328 this.editOwnItem.addActionListener(new ActionListener() {
330 * If the user has performed this action
332 * @param e An instance of an ActionEvent class
335 public void actionPerformed (final ActionEvent e) {
336 self.getClient().getContactManager().doChangeOwnData();
341 menu.add(this.editOwnItem);
343 // Add menu -> menu bar
346 // Add menu bar -> frame
347 this.frame.add(menuBar, BorderLayout.NORTH);
351 * Initializes status panel
353 private void initStatusPanel () {
354 // Init status label (which needs to be updated
355 this.statusLabel = new JLabel();
356 this.updateStatus("initializing");
358 // Init status bar in south
359 JPanel panel = new JPanel();
360 panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
361 panel.add(this.statusLabel);
362 panel.setBorder(BorderFactory.createEtchedBorder());
364 // Add panel to frame
365 this.frame.add(panel, BorderLayout.SOUTH);
369 * Initializes the table which will show all contacts
371 private void initTable () {
372 // Instance table model
373 this.dataModel = new ContactTableModel(this.getClient());
376 this.dataTable = new JTable(this.dataModel);
378 // Add mouse listener
379 this.dataTable.addMouseListener(new MouseAdapter() {
381 * If the user peformed a click on a cell
383 * @param e Mouse event instance
386 public void mouseClicked (final MouseEvent e) {
387 throw new UnsupportedOperationException("Unfinished.");
391 // Add table to frame
392 this.frame.add(this.dataTable, BorderLayout.CENTER);
396 * Updates status to given type
398 * @param type Status type
400 private void updateStatus (final String type) {
401 // Set status message
402 this.statusLabel.setText(this.getBundle().getString("AddressbookFrame.statusLabel." + type + ".text"));