From b584ed016789504e50546d3b43e2b202ff823fba Mon Sep 17 00:00:00 2001
From: Roland Haeder <roland@mxchange.org>
Date: Fri, 24 Jul 2015 15:33:50 +0200
Subject: [PATCH] =?utf8?q?Introduced=20new=20model=20as=20we=20need=20gend?=
 =?utf8?q?er=20value=20verfication,=20maybe=20this=20works=3F=20Signed-off?=
 =?utf8?q?-by:Roland=20H=C3=A4der=20<roland@mxchange.org>?=
MIME-Version: 1.0
Content-Type: text/plain; charset=utf8
Content-Transfer-Encoding: 8bit

---
 .../client/gui/AddressbookFrame.java          | 129 ++++++++++++++++--
 .../addressbook/client/gui/SwingClient.java   |  12 +-
 .../localization/bundle_de_DE.properties      |   3 +
 .../localization/bundle_en_US.properties      |   2 +
 .../mxchange/addressbook/model/BaseModel.java |  40 +++++-
 .../model/gender/GenderComboBoxModel.java     |  89 ++++++++++++
 6 files changed, 256 insertions(+), 19 deletions(-)
 create mode 100644 Addressbook/src/org/mxchange/addressbook/model/gender/GenderComboBoxModel.java

diff --git a/Addressbook/src/org/mxchange/addressbook/client/gui/AddressbookFrame.java b/Addressbook/src/org/mxchange/addressbook/client/gui/AddressbookFrame.java
index 8f8cee6d..2c9494ba 100644
--- a/Addressbook/src/org/mxchange/addressbook/client/gui/AddressbookFrame.java
+++ b/Addressbook/src/org/mxchange/addressbook/client/gui/AddressbookFrame.java
@@ -16,7 +16,9 @@
  */
 package org.mxchange.addressbook.client.gui;
 
+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;
@@ -26,13 +28,17 @@ 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;
@@ -67,6 +73,12 @@ public class AddressbookFrame extends BaseFrameworkSystem implements ClientFrame
 		// Return instance
 		return self;
 	}
+
+	/**
+	 * Dialog box "add contact"
+	 */
+	private JDialog addContact;
+
 	/**
 	 * Frame instance for "add own data"
 	 */
@@ -112,7 +124,8 @@ public class AddressbookFrame extends BaseFrameworkSystem implements ClientFrame
 		this.getLogger().trace(MessageFormat.format("client={0}: CALLED!", client));
 
 		// Set frame instance
-		this.frame = new JFrame(AddressbookApplication.printableTitle());
+		this.frame = new JFrame();
+		this.frame.setTitle(this.generateFrameTitle("main"));
 
 		// Set client here
 		this.setClient(client);
@@ -208,6 +221,82 @@ public class AddressbookFrame extends BaseFrameworkSystem implements ClientFrame
 		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)));
+		}
+
+		// 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
 	 */
@@ -257,6 +346,9 @@ public class AddressbookFrame extends BaseFrameworkSystem implements ClientFrame
 
 		// Init status panel
 		initStatusPanel();
+
+		// Init other windows
+		initOtherDialogs();
 	}
 
 	/**
@@ -267,12 +359,12 @@ public class AddressbookFrame extends BaseFrameworkSystem implements ClientFrame
 		JMenuBar menuBar = new JMenuBar();
 		JMenu menu;
 		JMenuItem item;
-
-	// Init some menus:
+		
+		// Init some menus:
 		// 1) File menu
 		menu = new JMenu(this.getBundle().getString("AddressbookFrame.menu.file.text"));
-
-	// Add menu items:
+		
+		// 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"));
@@ -295,8 +387,8 @@ public class AddressbookFrame extends BaseFrameworkSystem implements ClientFrame
 
 		// Add menu -> menu bar
 		menuBar.add(menu);
-
-	// Init some menus:
+		
+		// Init some menus:
 		// 2) Addressbook menu
 		menu = new JMenu(this.getBundle().getString("AddressbookFrame.menu.addressbook.text"));
 
@@ -347,6 +439,15 @@ public class AddressbookFrame extends BaseFrameworkSystem implements ClientFrame
 		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
 	 */
@@ -388,8 +489,16 @@ public class AddressbookFrame extends BaseFrameworkSystem implements ClientFrame
 			}
 		});
 
-		// Add table to frame
-		this.frame.add(this.dataTable, BorderLayout.CENTER);
+		// 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);
 	}
 
 	/**
@@ -399,6 +508,6 @@ public class AddressbookFrame extends BaseFrameworkSystem implements ClientFrame
 	 */
 	private void updateStatus (final String type) {
 		// Set status message
-		this.statusLabel.setText(this.getBundle().getString("AddressbookFrame.statusLabel." + type + ".text"));
+		this.statusLabel.setText(this.getBundle().getString(String.format("AddressbookFrame.statusLabel.%s.text", type)));
 	}
 }
diff --git a/Addressbook/src/org/mxchange/addressbook/client/gui/SwingClient.java b/Addressbook/src/org/mxchange/addressbook/client/gui/SwingClient.java
index c9ed4f6d..a9ba1c1f 100644
--- a/Addressbook/src/org/mxchange/addressbook/client/gui/SwingClient.java
+++ b/Addressbook/src/org/mxchange/addressbook/client/gui/SwingClient.java
@@ -84,11 +84,19 @@ public class SwingClient extends BaseClient implements Client {
 		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
 	}
 
+	/**
+	 * Shows dialog to enter new contact
+	 * 
+	 * @return Returns finished Contact instance
+	 */
 	@Override
 	public Contact doEnterOwnData () {
 		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
 	}
 
+	/**
+	 * Shuts down this client
+	 */
 	@Override
 	public void doShutdown () {
 		// Debug message
@@ -100,14 +108,14 @@ public class SwingClient extends BaseClient implements Client {
 		// Shutdown frame
 		this.frame.doShutdown();
 
-	// @TODO Add other shutdown stuff
+		// @TODO Add other shutdown stuff
 		// Debug message
 		this.getLogger().trace("EXIT!");
 	}
 
 	@Override
 	public void doUserMenuChoice () throws UnhandledUserChoiceException {
-	// Debug message
+		// Debug message
 		//* NOISY-DEBUG: */ this.getLogger().trace("CALLED!");
 
 		// Not implemented here
diff --git a/Addressbook/src/org/mxchange/addressbook/localization/bundle_de_DE.properties b/Addressbook/src/org/mxchange/addressbook/localization/bundle_de_DE.properties
index 1239e979..f873060b 100644
--- a/Addressbook/src/org/mxchange/addressbook/localization/bundle_de_DE.properties
+++ b/Addressbook/src/org/mxchange/addressbook/localization/bundle_de_DE.properties
@@ -24,6 +24,9 @@ AddressbookFrame.menuItem.addOwnData.text=Eigene Adresse hinzuf\u00fcgen
 AddressbookFrame.menuItem.addOwnData.toolTipText=Erlaubt das Hinzuf\u00fcgen eigener Daten.
 AddressbookFrame.menuItem.editOwnData.text=Eigene Adresse \u00e4ndern
 AddressbookFrame.menuItem.editOwnData.toolTipText=Erlaubt das \u00c4ndern eigener Daten.
+AddressbookFrame.dialog.addContact.title.text=Neue Adresse hinzuf\u00fcgen
+AddressbookFrame.main.title.text=Adressen auflisten
+AddressbookFrame.border.name.title.text=Anrede, Vorname, Nachname
 ContactManager.columnName.gender.text=Anrede
 ContactManager.columnName.surname.text=Vorname
 ContactManager.columnName.familyName.text=Nachname
diff --git a/Addressbook/src/org/mxchange/addressbook/localization/bundle_en_US.properties b/Addressbook/src/org/mxchange/addressbook/localization/bundle_en_US.properties
index e8c1bf4a..46addd1d 100644
--- a/Addressbook/src/org/mxchange/addressbook/localization/bundle_en_US.properties
+++ b/Addressbook/src/org/mxchange/addressbook/localization/bundle_en_US.properties
@@ -24,6 +24,8 @@ AddressbookFrame.menuItem.addOwnData.text=Add own address
 AddressbookFrame.menuItem.addOwnData.toolTipText=Allows the user to add own address data
 AddressbookFrame.menuItem.editOwnData.text=Edit own data
 AddressbookFrame.menuItem.editOwnData.toolTipText=Allows the user to edit own address data
+AddressbookFrame.dialog.addContact.title.text=Add new address
+AddressbookFrame.main.title.text=List addresses
 ContactManager.columnName.gender.text=Gender
 ContactManager.columnName.surname.text=Surname
 ContactManager.columnName.familyName.text=Family name
diff --git a/Addressbook/src/org/mxchange/addressbook/model/BaseModel.java b/Addressbook/src/org/mxchange/addressbook/model/BaseModel.java
index cc74cad8..22c7e8d3 100644
--- a/Addressbook/src/org/mxchange/addressbook/model/BaseModel.java
+++ b/Addressbook/src/org/mxchange/addressbook/model/BaseModel.java
@@ -18,6 +18,7 @@ package org.mxchange.addressbook.model;
 
 import java.text.MessageFormat;
 import javax.swing.event.EventListenerList;
+import javax.swing.event.ListDataListener;
 import javax.swing.event.TableModelListener;
 import org.mxchange.addressbook.BaseFrameworkSystem;
 
@@ -26,18 +27,30 @@ import org.mxchange.addressbook.BaseFrameworkSystem;
  * @author Roland Haeder
  */
 public class BaseModel extends BaseFrameworkSystem {
-
 	/**
-	 * List of listeners
+	 * List of event listeners
 	 */
-	private final EventListenerList listenerList;
+	private final EventListenerList eventListenerList;
 
 	/**
 	 * Protected constructor
 	 */
 	protected BaseModel () {
 		// Init listener list
-		this.listenerList = new EventListenerList();
+		this.eventListenerList = new EventListenerList();
+	}
+
+	/**
+	 * Adds a lister of this type to the list
+	 *
+	 * @param listener Listener instance
+	 */
+	public void addListDataListener (final ListDataListener listener) {
+		// Debug message
+		this.getLogger().debug(MessageFormat.format("Adding listener {0} ...", listener.getClass()));
+		
+		// Remove listener
+		this.eventListenerList.add(ListDataListener.class, listener);
 	}
 
 	/**
@@ -50,19 +63,32 @@ public class BaseModel extends BaseFrameworkSystem {
 		this.getLogger().debug(MessageFormat.format("Adding listener {0} ...", listener.getClass()));
 
 		// Add listener
-		this.listenerList.add(TableModelListener.class, listener);
+		this.eventListenerList.add(TableModelListener.class, listener);
 	}
 
 	/**
-	 * Removes a TableModel listener instance from the event list.
+	 * Removes given listener
 	 *
 	 * @param listener Listener instance
 	 */
+	public void removeListDataListener (final ListDataListener listener) {
+		// Debug message
+		this.getLogger().debug(MessageFormat.format("Removing listener {0} ...", listener.getClass()));
+
+		// Remove listener
+		this.eventListenerList.remove(ListDataListener.class, listener);
+	}
+
+	/**
+	 * Removes a TableModel listener instance from the event list.
+	 * 
+	 * @param listener Listener instance
+	 */
 	public void removeTableModelListener (final TableModelListener listener) {
 		// Debug message
 		this.getLogger().debug(MessageFormat.format("Removing listener {0} ...", listener.getClass()));
 
 		// Remove listener
-		this.listenerList.remove(TableModelListener.class, listener);
+		this.eventListenerList.remove(TableModelListener.class, listener);
 	}
 }
diff --git a/Addressbook/src/org/mxchange/addressbook/model/gender/GenderComboBoxModel.java b/Addressbook/src/org/mxchange/addressbook/model/gender/GenderComboBoxModel.java
new file mode 100644
index 00000000..0b0a46dd
--- /dev/null
+++ b/Addressbook/src/org/mxchange/addressbook/model/gender/GenderComboBoxModel.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2015 Roland Haeder
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mxchange.addressbook.model.gender;
+
+import javax.swing.ComboBoxModel;
+import org.mxchange.addressbook.client.Client;
+import org.mxchange.addressbook.model.BaseModel;
+
+/**
+ *
+ * @author Roland Haeder
+ */
+public class GenderComboBoxModel extends BaseModel implements ComboBoxModel<String> {
+
+	/**
+	 * Selected item instance, the value can only be 'M', 'F' or 'C'
+	 */
+	private char selectedItem = 0;
+
+	/**
+	 * Selectable items
+	 */
+	private final char[] validItems = new char[] {'M', 'F', 'C'};
+
+	/**
+	 * Creates an instance of this model with a Client instance
+	 * @param client Client instance
+	 */
+	public GenderComboBoxModel (final Client client) {
+		// Call super constructor
+		super();
+
+		// Set client
+		this.setClient(client);
+	}
+
+	@Override
+	public String getElementAt (final int index) {
+		// Return it
+		return String.valueOf(this.validItems[index]);
+	}
+
+	/**
+	 * Gets the currently selected item or null if nothing is selected.
+	 * 
+	 * @return Selected item or null
+	 */
+	@Override
+	public Object getSelectedItem () {
+		// Is the char set other than 0?
+		if (this.selectedItem == 0) {
+			// Nothing selected
+			return null;
+		}
+
+		// Return string representing the selected item
+		return this.selectedItem;
+	}
+
+	@Override
+	public void setSelectedItem (final Object anItem) {
+		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+	}
+
+	/**
+	 * Getter for size. Here only 3 values are valid: M, F and C
+	 *
+	 * @return Maximum size
+	 */
+	@Override
+	public int getSize () {
+		// Get size of array
+		return this.validItems.length;
+	}
+}
-- 
2.39.5