+
+ /**
+ * 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 initialized;
+
+ /**
+ * 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)); //NOI18N
+
+ // Set frame instance
+ this.frame = new JFrame();
+ this.frame.setTitle(this.generateFrameTitle("main")); //NOI18N
+
+ // Set client here
+ this.setClient(client);
+
+ // Trace message
+ this.getLogger().trace("EXIT!"); //NOI18N
+ }
+
+ @Override
+ public Contact doEnterOwnData () {
+ // Trace message
+ this.getLogger().trace("CALLED!"); //NOI18N
+
+ // Is the "add contact" window visible?
+ if (this.addContact.isVisible()) {
+ // Something bad happened
+ throw new IllegalStateException("Window addContact is already visible."); //NOI18N
+ }
+
+ // Disable main window
+ this.frame.setEnabled(false);
+
+ // Make other window visible
+ this.addContact.setVisible(true);
+
+ // Trace message
+ this.getLogger().trace("Returning null : EXIT!"); //NOI18N
+
+ // Return value is not supported
+ return null;
+ }
+
+ /**
+ * Shutdown this frame
+ */
+ @Override
+ public void doShutdown () {
+ // Trace message
+ this.getLogger().trace("CALLED!"); //NOI18N
+
+ // First only show shutdown status
+ this.updateStatus("shutdown"); //NOI18N
+
+ // Trace message
+ this.getLogger().trace("EXIT!"); //NOI18N
+ }
+
+
+ /**
+ * Enables main window (frame)
+ */
+ @Override
+ public void enableMainWindow () {
+ // Trace message
+ this.getLogger().trace("CALLED!"); //NOI18N
+
+ // Enable it again
+ this.frame.setEnabled(true);
+
+ // Request focus for this window
+ this.frame.requestFocus();
+
+ // Trace message
+ this.getLogger().trace("EXIT!"); //NOI18N
+ }
+
+ /**
+ * 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)); //NOI18N
+
+ // Get and cast manager instance
+ ManageableContact manager = (ManageableContact) this.getClient().getManager();
+
+ // Has the user entered own data?
+ if (manager.isOwnContactAdded()) {
+ // Debug message
+ this.getLogger().debug("Disabling menus: isOwnContactAdded()=false"); //NOI18N
+
+ // 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"); //NOI18N
+
+ // Trace message
+ this.getLogger().trace("EXIT!"); //NOI18N
+ }
+
+ /**
+ * 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!"); //NOI18N
+
+ // Has this frame been initialized?
+ if (this.isInitialized()) {
+ // Throw exception
+ throw new FrameAlreadyInitializedException();
+ }
+
+ // Init components
+ this.initComponents();
+
+ // Set flag
+ this.initialized = true;
+
+ // Trace message
+ this.getLogger().trace("EXIT!"); //NOI18N
+ }
+
+ /**
+ * Returns field isInitialized. This flag indicates whether this frame has
+ * been initialized or not.
+ *
+ * @return Field isInitialized
+ */
+ @Override
+ public final boolean isInitialized () {
+ return this.initialized;
+ }
+
+ /**
+ * Shuts down the application.
+ */
+ @Override
+ public void shutdownApplication () {
+ // Trace message
+ this.getLogger().trace("CALLED!"); //NOI18N
+
+ // 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."); //NOI18N
+ return;
+ }
+
+ // Call shutdown method
+ this.getClient().getApplication().doShutdown();
+
+ // Trace message
+ this.getLogger().trace("EXIT!"); //NOI18N
+ }
+
+ /**
+ * Adds a JTextField with label and tool tip to given panel
+ *
+ * @param panel Panel instance to add text field
+ * @param key Part of message key from resource bundle
+ * @param fieldLength Length of text field
+ */
+ private void addTextFieldWithLabelToPanel (final JPanel panel, final String key, final int fieldLength) {
+ // Trace message
+ this.getLogger().trace(MessageFormat.format("panel={0},key={1},fieldLength={2} - CALLED!", panel, key, fieldLength)); //NOI18N
+
+ // Init label for given key
+ JLabel label = new JLabel(this.getBundle().getString(String.format("AddressbookFrame.%s.text", key))); //NOI18N
+
+ // And input box wih tool tip
+ JTextField field = new JTextField(fieldLength);
+ field.setToolTipText(this.getBundle().getString(String.format("AddressbookFrame.%s.toolTipText", key))); //NOI18N
+
+ // Add both to panel
+ panel.add(label);
+ panel.add(field);
+
+ // Trace message
+ this.getLogger().trace("EXIT!"); //NOI18N
+ }
+
+ /**
+ * 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)); //NOI18N
+ }
+
+ /**
+ * 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))); //NOI18N
+ }
+
+ // Return it
+ return title;
+ }
+
+ /**
+ * Initializes "add" and "cancel" buttons
+ */
+ private void initAddCancelButtons () {
+ // Trace message
+ this.getLogger().trace("CALLED!"); //NOI18N
+
+ // Init panel
+ JPanel panel = new JPanel();
+ panel.setLayout(new GridLayout(1, 2, 10, 10));
+
+ // Generate "add" button
+ JButton addButton = new JButton(this.getBundle().getString("AddressbookFrame.button.addAddress.text"));
+
+ // Add listener
+ addButton.addActionListener(new AddActionListener(this.addContact, this));
+
+ // Add button to panel
+ panel.add(addButton);
+
+ // Generate "cancel" button
+ JButton cancelButton = new JButton(this.getBundle().getString("AddressbookFrame.button.cancel.text"));
+
+ // Add listener
+ cancelButton.addActionListener(new CancelActionListener(this.addContact, this));
+
+ // Add button to panel
+ panel.add(cancelButton);
+
+ // Add panel to main panel
+ this.addContact.add(panel);
+
+ // Trace message
+ this.getLogger().trace("EXIT!"); //NOI18N
+ }
+
+ /**
+ * Initializes "add contact" dialog
+ */
+ private void initAddContactDialog () {
+ // Trace message
+ this.getLogger().trace("CALLED!"); //NOI18N
+
+ // Instance dialog and set title
+ this.addContact = new JDialog();
+ this.addContact.setTitle(this.generateFrameTitle("dialog.addContact")); //NOI18N
+
+ // Set layout
+ this.addContact.setLayout(new GridLayout(0, 1, 2, 2));
+
+ // Only hide it on close and make it appear in middle of screen
+ this.addContact.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
+ this.addContact.setLocationRelativeTo(this.frame);
+
+ // Set always on top and auto-focus
+ this.addContact.setAlwaysOnTop(true);
+ this.addContact.setAutoRequestFocus(true);
+
+ // Initial dimension
+ this.addContact.setSize(500, 500);
+
+ // And it is not resizeable
+ this.addContact.setResizable(false);
+
+ /*
+ * Add listener which asks for confirmation, if data has been entered
+ * but not saved yet. The user may appriciate this ... ;-)
+ *
+ * @TODO Unfinished
+ */
+ this.addContact.addWindowListener(new WindowAdapter() {
+ /**
+ * Invoked when a window has been closed.
+ */
+ @Override
+ public void windowClosed (final WindowEvent e) {
+ // Enable main window again
+ AddressbookFrame.getSelfInstance(null).enableMainWindow();
+ }
+
+ /**
+ * 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) {
+ e.getWindow().dispose();
+ }
+ });
+
+ // Init 3 panels:
+ // 1) "name" panel
+ initNameDataPanel(this.addContact);
+
+ // 2) "address" panel
+ initAddressDataPanel(this.addContact);
+
+ // 3) "other" panel
+ initOtherDataPanel(this.addContact);
+
+ // 4) "Add" and "Cancel" buttons, combined they are unique for this dialog
+ initAddCancelButtons();
+
+ // x)Only for developing:
+ /* DEBUG: */ this.addContact.setVisible(true);
+
+ // Trace message
+ this.getLogger().trace("EXIT!"); //NOI18N
+ }
+
+ /**
+ * Initializes address panel
+ *
+ * @param dialog A JDialog instance to this components to
+ */
+ private void initAddressDataPanel (final JDialog dialog) {
+ // Trace message
+ this.getLogger().trace("CALLED!"); //NOI18N
+
+ // Panel "address" input boxes
+ JPanel addressPanel = new JPanel();
+ addressPanel.setLayout(new GridLayout(0, 4, 3, 3));
+
+ // Set border to titled version
+ addressPanel.setBorder(new TitledBorder(this.generateBorderTitle("address"))); //NOI18N
+
+ // Add text field for street
+ this.addTextFieldWithLabelToPanel(addressPanel, "street", 20); //NOI18N
+
+ // Number label
+ JLabel numberLabel = new JLabel(this.getBundle().getString("AddressbookFrame.number.text"));
+
+ // And text field, but only accept numbers
+ JFormattedTextField number = new JFormattedTextField();
+ number.setToolTipText(this.getBundle().getString("AddressbookFrame.number.toolTipText"));
+
+ // Add both to street panel
+ addressPanel.add(numberLabel);
+ addressPanel.add(number);
+
+ // Label for ZIP code, again numbers only
+ JLabel zipLabel = new JLabel(this.getBundle().getString("AddressbookFrame.zip.text"));
+
+ // Init text field with label
+ JFormattedTextField zip = new JFormattedTextField();
+ zip.setToolTipText(this.getBundle().getString("AddressbookFrame.zip.toolTipText"));
+
+ // Add both to street panel
+ addressPanel.add(zipLabel);
+ addressPanel.add(zip);
+
+ // Add text field for city name
+ this.addTextFieldWithLabelToPanel(addressPanel, "city", 20); //NOI18N
+
+ // Add panel to dialog
+ dialog.add(addressPanel);
+
+ // Trace message
+ this.getLogger().trace("EXIT!"); //NOI18N
+ }
+
+ /**
+ * Initialize components
+ */
+ private void initComponents () {
+ // Debug line
+ this.getLogger().trace("CALLED!"); //NOI18N
+
+ // 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();
+
+ // Trace message
+ this.getLogger().trace("EXIT!"); //NOI18N