]> git.mxchange.org Git - addressbook-swing.git/blobdiff - Addressbook/src/org/mxchange/addressbook/client/gui/AddressbookFrame.java
Introduced new model as we need gender value verfication, maybe this works?
[addressbook-swing.git] / Addressbook / src / org / mxchange / addressbook / client / gui / AddressbookFrame.java
index 1a629c03fffe1ab7d50bf5594f61a5de0f19f4be..2c9494ba812137d68af8c272ef71db5380a245dc 100644 (file)
  */
 package org.mxchange.addressbook.client.gui;
 
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.mxchange.addressbook.application.Application;
+import org.mxchange.addressbook.model.gender.GenderComboBoxModel;
+import java.awt.BorderLayout;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.text.MessageFormat;
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.border.TitledBorder;
+import javax.swing.table.TableModel;
+import org.mxchange.addressbook.BaseFrameworkSystem;
+import org.mxchange.addressbook.application.AddressbookApplication;
 import org.mxchange.addressbook.client.Client;
-import org.mxchange.addressbook.manager.contact.ManageableContact;
+import org.mxchange.addressbook.exceptions.FrameAlreadyInitializedException;
+import org.mxchange.addressbook.model.contact.ContactTableModel;
 
 /**
  *
  * @author Roland Haeder
  */
-public class AddressbookFrame extends javax.swing.JFrame implements ClientFrame {
-    /**
-     * Class' logger
-     */
-    private final Logger LOG;
-
-    /**
-     * Client instance
-     */
-    private final Client client;
-
-    /**
-     * Initialize object
-     */
-    {
-       LOG = LogManager.getLogger(this);
-    }
-
-    /**
-     * Creates an instance of this frame with a client instance
-     * @param client 
-     */
-    public AddressbookFrame (final Client client) {
-       // Debug line
-       this.getLogger().debug("Initializing Swing frame ...");
-
-       // Init components
-       initComponents();
-
-       // Set client here
-       this.client = client;
-    }
-
-    @Override
-    public Application getApplication () {
-       throw new UnsupportedOperationException("Not implemented.");
-    }
-
-    @Override
-    public final Client getClient () {
-       return this.client;
-    }
-
-    @Override
-    public ManageableContact getContactManager () {
-       throw new UnsupportedOperationException("Not implemented.");
-    }
-
-    /**
-     * This method is called from within the constructor to initialize the form.
-     * WARNING: Do NOT modify this code. The content of this method is always
-     * regenerated by the Form Editor.
-     */
-    @SuppressWarnings ("unchecked")
-    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
-    private void initComponents() {
-
-        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
-
-        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
-        getContentPane().setLayout(layout);
-        layout.setHorizontalGroup(
-            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGap(0, 400, Short.MAX_VALUE)
-        );
-        layout.setVerticalGroup(
-            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGap(0, 300, Short.MAX_VALUE)
-        );
-
-        pack();
-    }// </editor-fold>//GEN-END:initComponents
-
-    /**
-     * Initializes the frame
-     */
-    @Override
-    public void initFrame (final Client client) {
-       /*
-        * Set the Nimbus look and feel
-        */
-        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
-        /*
-        * If Nimbus (introduced in Java SE 6) is not available, stay with the
-        * default look and feel. For details see
-        * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
-        */
-       try {
-           for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
-               if ("Nimbus".equals(info.getName())) {
-                   javax.swing.UIManager.setLookAndFeel(info.getClassName());
-                   break;
+public class AddressbookFrame extends BaseFrameworkSystem implements ClientFrame {
+
+       /**
+        * Own instance
+        */
+       private static ClientFrame self;
+
+       /**
+        * Singelton getter for this frame instance.
+        *
+        * @param client Client instance
+        * @return Returns a singelton instance of this frame
+        */
+       public static final ClientFrame getSelfInstance (final Client client) {
+               // Is it set?
+               if (!(self instanceof ClientFrame)) {
+                       // Create new instance
+                       self = new AddressbookFrame(client);
+               }
+
+               // Return instance
+               return self;
+       }
+
+       /**
+        * Dialog box "add contact"
+        */
+       private JDialog addContact;
+
+       /**
+        * Frame instance for "add own data"
+        */
+       private JMenuItem addOwnItem;
+
+       /**
+        * Instance to table model
+        */
+       private TableModel dataModel;
+
+       /**
+        * Table instance
+        */
+       private JTable dataTable;
+
+       /**
+        * Frame instance for "edit own data"
+        */
+       private JMenuItem editOwnItem;
+
+       /**
+        * Frame instance
+        */
+       private final JFrame frame;
+
+       /**
+        * Whether this frame has been initialized
+        */
+       private boolean isInitialized;
+
+       /**
+        * Status label needs to be updated
+        */
+       private JLabel statusLabel;
+
+       /**
+        * Creates an instance of this frame with a client instance
+        *
+        * @param client
+        */
+       private AddressbookFrame (final Client client) {
+               // Debug line
+               this.getLogger().trace(MessageFormat.format("client={0}: CALLED!", client));
+
+               // Set frame instance
+               this.frame = new JFrame();
+               this.frame.setTitle(this.generateFrameTitle("main"));
+
+               // Set client here
+               this.setClient(client);
+       }
+
+       /**
+        * Shutdown this frame
+        */
+       @Override
+       public void doShutdown () {
+               // First only show shutdown status
+               this.updateStatus("shutdown");
+       }
+
+       /**
+        * Setups the frame, do not set isInitialized here
+        *
+        * @param client Client instance
+        */
+       @Override
+       public void setupFrame (final Client client) {
+               // Debug line
+               this.getLogger().trace(MessageFormat.format("client={0}: CALLED!", client));
+
+               // Has the user entered own data?
+               if (this.getClient().getContactManager().isOwnContactAdded()) {
+                       // Debug message
+                       this.getLogger().debug("Disabling menus: isOwnContactAdded()=false");
+
+                       // Not entered yet, so disable "add" menu
+                       this.addOwnItem.setEnabled(false);
+               } else {
+                       // Disable "edit"
+                       this.editOwnItem.setEnabled(false);
+               }
+
+               // Make the frame visible
+               this.frame.setVisible(true);
+
+               // All done here
+               this.updateStatus("done");
+       }
+
+       /**
+        * Initalizes this frame. Having initComponents() exposed (publicly
+        * accessible) means that any other object can initialize components which
+        * you may not want.
+        *
+        * @throws
+        * org.mxchange.addressbook.exceptions.FrameAlreadyInitializedException If
+        * this method has been called twice
+        */
+       @Override
+       public void init () throws FrameAlreadyInitializedException {
+               // Debug line
+               this.getLogger().trace("CALLED!");
+
+               // Has this frame been initialized?
+               if (this.isInitialized()) {
+                       // Throw exception
+                       throw new FrameAlreadyInitializedException();
+               }
+
+               // Init components
+               this.initComponents();
+
+               // Set flag
+               this.isInitialized = true;
+       }
+
+       /**
+        * Returns field isInitialized. This flag indicates whether this frame has
+        * been initialized or not.
+        *
+        * @return Field isInitialized
+        */
+       @Override
+       public final boolean isInitialized () {
+               return this.isInitialized;
+       }
+
+       /**
+        * Shuts down the application.
+        */
+       @Override
+       public void shutdownApplication () {
+               // To do this, the frame must be initialized
+               if (!this.isInitialized()) {
+                       // Not initalized, so bad call
+                       this.getLogger().fatal("Bad call of shutdownApplication(). Please report this.");
+                       return;
+               }
+               this.getClient().getApplication().doShutdown();
+       }
+
+       /**
+        * Generates a title for borders
+        * @param key Key part to look for
+        * @return Human-readable title
+        */
+       private String generateBorderTitle (final String key) {
+               // Call bundle instance
+               return this.getBundle().getString(String.format("AddressbookFrame.border.%s.title.text", key));
+       }
+
+       /**
+        * Generates a title for all frames based on given sub title key. If null is
+        * given, the sub title is not generated.
+        * 
+        * @param subKey Key for sub title resource
+        * @return A full application title
+        */
+       private String generateFrameTitle (final String subKey) {
+               // Base title
+               String title = AddressbookApplication.printableTitle();
+
+               // Is key given?
+               if (subKey != null) {
+                       // Add sub title
+                       title = String.format("%s - %s", title, this.getBundle().getString(String.format("AddressbookFrame.%s.title.text", subKey)));
                }
-           }
-       } catch (final ClassNotFoundException ex) {
-           this.getLogger().catching(ex);
-       } catch (final InstantiationException ex) {
-           this.getLogger().catching(ex);
-       } catch (final IllegalAccessException ex) {
-           this.getLogger().catching(ex);
-       } catch (final javax.swing.UnsupportedLookAndFeelException ex) {
-           this.getLogger().catching(ex);
-       }
-        //</editor-fold>
-
-       // Debug line
-       this.getLogger().debug("Displaying form ...");
-
-       /*
-        * Create and display the form
-        */
-       java.awt.EventQueue.invokeLater(new Runnable() {
-           @Override
-           public void run () {
-               new AddressbookFrame(client).setVisible(true);
-           }
-       });
-    }
-
-    /**
-     * Getter for logger
-     *
-     * @return Logger
-     */
-    protected final Logger getLogger () {
-       return this.LOG;
-    }
-
-    // Variables declaration - do not modify//GEN-BEGIN:variables
-    // End of variables declaration//GEN-END:variables
+
+               // Return it
+               return title;
+       }
+
+       /**
+        * Initializes "add contact" dialog
+        */
+       private void initAddContactDialog () {
+               // Instance dialog and set title
+               this.addContact = new JDialog();
+               this.addContact.setTitle(this.generateFrameTitle("dialog.addContact"));
+               this.addContact.setLayout(new GridLayout(4, 1));
+               
+               // Only hide it on close and make it appear in middle of screen
+               this.addContact.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
+               this.addContact.setLocationRelativeTo(null);
+               
+               // Set always on top and auto-focus
+               this.addContact.setAlwaysOnTop(true);
+               this.addContact.setAutoRequestFocus(true);
+               
+               // Initial dimension
+               this.addContact.setSize(400, 300);
+               
+               /*
+                * Add listener which asks for confirmation, if data has been entered
+                * but not saved yet. The user may appriciate this ... ;-)
+                *
+                * @TODO Unfinished
+                */
+               
+               // Init 3 panels:
+               // 1) Panel "name" input boxes
+               JPanel panel = new JPanel();
+               panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
+               
+               // Set border to titled version
+               panel.setBorder(new TitledBorder(this.generateBorderTitle("name")));
+
+               // Add some input boxes for "name" panel
+               JComboBox<String> gender = new JComboBox<>(new GenderComboBoxModel(this.getClient()));
+
+               // Finally add panel to dialog
+               this.addContact.add(panel);
+               
+               // Only for developing:
+               /* DEBUG: */ this.addContact.setVisible(true);
+       }
+
+       /**
+        * Initialize components
+        */
+       private void initComponents () {
+               // Debug line
+               this.getLogger().trace("CALLED!");
+
+               // Set default close operation
+               this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+               // Register shutdown listener
+               this.frame.addWindowListener(new WindowAdapter() {
+                       /**
+                        * Invoked when a window has been closed.
+                        */
+                       @Override
+                       public void windowClosed (final WindowEvent e) {
+                               // Shutdown application cleanly
+                               self.shutdownApplication();
+                       }
+
+                       /**
+                        * Invoked when a window is in the process of being closed. The
+                        * close operation can be overridden at this point.
+                        */
+                       @Override
+                       public void windowClosing (final WindowEvent e) {
+                               // Also shutdown cleanly here
+                               self.shutdownApplication();
+                       }
+               });
+
+               // Setup layout manager
+               this.frame.setLayout(new BorderLayout(2, 2));
+
+               // Set window size
+               this.frame.setSize(700, 400);
+
+               // Center window in middle of screen, instead of top-left corner
+               this.frame.setLocationRelativeTo(null);
+
+               // Init menu system
+               initMenuSystem();
+
+               // Init table
+               initTable();
+
+               // Init status panel
+               initStatusPanel();
+
+               // Init other windows
+               initOtherDialogs();
+       }
+
+       /**
+        * Initializes the menu system
+        */
+       private void initMenuSystem () {
+               // Init menu bar, menu and item instances
+               JMenuBar menuBar = new JMenuBar();
+               JMenu menu;
+               JMenuItem item;
+               
+               // Init some menus:
+               // 1) File menu
+               menu = new JMenu(this.getBundle().getString("AddressbookFrame.menu.file.text"));
+               
+               // Add menu items:
+               // 1.x) Exit program (should be last)
+               item = new JMenuItem(this.getBundle().getString("AddressbookFrame.menuItem.exitProgram.text"));
+               item.setToolTipText(this.getBundle().getString("AddressbookFrame.menuItem.exitProgram.toolTipText"));
+
+               // Add listener to exit menu
+               item.addActionListener(new ActionListener() {
+                       /**
+                        * If the user has performed this action
+                        *
+                        * @param e An instance of an ActionEvent class
+                        */
+                       @Override
+                       public void actionPerformed (final ActionEvent e) {
+                               self.shutdownApplication();
+                       }
+               });
+
+               // Add item -> menu
+               menu.add(item);
+
+               // Add menu -> menu bar
+               menuBar.add(menu);
+               
+               // Init some menus:
+               // 2) Addressbook menu
+               menu = new JMenu(this.getBundle().getString("AddressbookFrame.menu.addressbook.text"));
+
+               // 2.1) Add own data
+               this.addOwnItem = new JMenuItem(this.getBundle().getString("AddressbookFrame.menuItem.addOwnData.text"));
+               this.addOwnItem.setToolTipText(this.getBundle().getString("AddressbookFrame.menuItem.addOwnData.toolTipText"));
+
+               // Add listener to exit menu
+               this.addOwnItem.addActionListener(new ActionListener() {
+                       /**
+                        * If the user has performed this action
+                        *
+                        * @param e An instance of an ActionEvent class
+                        */
+                       @Override
+                       public void actionPerformed (final ActionEvent e) {
+                               self.getClient().getContactManager().doEnterOwnData();
+                       }
+               });
+
+               // Add item -> menu
+               menu.add(this.addOwnItem);
+
+               // 2.2) Edit own data
+               this.editOwnItem = new JMenuItem(this.getBundle().getString("AddressbookFrame.menuItem.editOwnData.text"));
+               this.editOwnItem.setToolTipText(this.getBundle().getString("AddressbookFrame.menuItem.editOwnData.toolTipText"));
+
+               // Add listener to exit menu
+               this.editOwnItem.addActionListener(new ActionListener() {
+                       /**
+                        * If the user has performed this action
+                        *
+                        * @param e An instance of an ActionEvent class
+                        */
+                       @Override
+                       public void actionPerformed (final ActionEvent e) {
+                               self.getClient().getContactManager().doChangeOwnData();
+                       }
+               });
+
+               // Add item -> menu
+               menu.add(this.editOwnItem);
+
+               // Add menu -> menu bar
+               menuBar.add(menu);
+
+               // Add menu bar -> frame
+               this.frame.add(menuBar, BorderLayout.NORTH);
+       }
+
+       /**
+        * Initialize other dialogs (e.g. "Add contact")
+        */
+       private void initOtherDialogs () {
+               // Init other windows:
+               // 1) Add contact
+               initAddContactDialog();
+       }
+
+       /**
+        * Initializes status panel
+        */
+       private void initStatusPanel () {
+               // Init status label (which needs to be updated
+               this.statusLabel = new JLabel();
+               this.updateStatus("initializing");
+
+               // Init status bar in south
+               JPanel panel = new JPanel();
+               panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
+               panel.add(this.statusLabel);
+               panel.setBorder(BorderFactory.createEtchedBorder());
+
+               // Add panel to frame
+               this.frame.add(panel, BorderLayout.SOUTH);
+       }
+
+       /**
+        * Initializes the table which will show all contacts
+        */
+       private void initTable () {
+               // Instance table model
+               this.dataModel = new ContactTableModel(this.getClient());
+
+               // Instance table
+               this.dataTable = new JTable(this.dataModel);
+
+               // Add mouse listener
+               this.dataTable.addMouseListener(new MouseAdapter() {
+                       /**
+                        * If the user peformed a click on a cell
+                        *
+                        * @param e Mouse event instance
+                        */
+                       @Override
+                       public void mouseClicked (final MouseEvent e) {
+                               throw new UnsupportedOperationException("Unfinished.");
+                       }
+               });
+
+               // Instance scroll pane
+               JScrollPane scroller = new JScrollPane();
+
+               // Add table to scroll pane
+               scroller.setViewportView(this.dataTable);
+               scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
+               scroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+
+               // Add pane to frame
+               this.frame.add(scroller, BorderLayout.CENTER);
+       }
+
+       /**
+        * Updates status to given type
+        *
+        * @param type Status type
+        */
+       private void updateStatus (final String type) {
+               // Set status message
+               this.statusLabel.setText(this.getBundle().getString(String.format("AddressbookFrame.statusLabel.%s.text", type)));
+       }
 }