package de.thk.addressbook.presentation;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import de.thk.addressbook.logic.Address;
import de.thk.addressbook.logic.AddressFormatException;
import de.thk.addressbook.logic.AddressbookManager;
import de.thk.addressbook.persistence.StorageException;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JTextField;
import java.awt.Button;
import java.awt.TextField;
import java.awt.Panel;
import javax.swing.JTextPane;
import javax.swing.JLabel;
import java.awt.Font;
public class AddressbookWindow {
private AddressbookManager addressbookManager;
private JFrame frmAddressbook;
/**
* Erzeugung der Applikation
*/
public AddressbookWindow() {
addressbookManager = new AddressbookManager();
initialize();
}
/**
* Initializierung des Applikations-Fensters. Hierbei werden insbesondere
* Event-Listener bei den Oberflächen-Elementen registriert.
*/
private void initialize() {
// Hauptfenster frmAddressbuch
setFrmAddressbook(new JFrame());
getFrmAddressbook().setTitle("Adressbuch");
getFrmAddressbook().setBounds(100, 100, 758, 472);
getFrmAddressbook().setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getFrmAddressbook().getContentPane().setLayout(null);
/* Auswahlliste lstAddressList
*
* Die Auswahlliste 'lstAddressList' ist eine View, die auf dem
* Modell 'listModel' basiert, d.h. das listModel beinhaltet die
* ver�nderlichen Daten in Rohform, die lstAddressList anzeigt.
*/
final DefaultListModel<Address> listModel = new DefaultListModel<>();
try {
for (Address address : addressbookManager.loadAddresses()) {
listModel.addElement(address);
}
} catch (StorageException e1) {
JOptionPane.showMessageDialog(getFrmAddressbook(), e1.getMessage());
e1.printStackTrace();
}
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(10, 11, 303, 363);
frmAddressbook.getContentPane().add(scrollPane);
final JList<Address> lstAddressList = new JList<>(listModel);
lstAddressList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
/* TODO: valueChanged implementieren
*
* Sorgen Sie dafür dass, bei der Änderung der Selektion die Addressbestandteile
* der selektierten Addresse in die (unten zu implementierenden) Eingabefelder
* übertragen werden.
*/
}
});
scrollPane.setViewportView(lstAddressList);
lstAddressList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
Button button = new Button("Neue Adresse");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JList <Address> nlistModel = new JList<>(listModel);
}
});
button.setBounds(29, 401, 116, 22);
frmAddressbook.getContentPane().add(button);
Button button_1 = new Button("Speichern");
button_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//System.out.println(e.getActionCommand());
}
});
button_1.setBounds(204, 401, 109, 22);
frmAddressbook.getContentPane().add(button_1);
TextField textField = new TextField();
textField.setBounds(457, 46, 254, 22);
frmAddressbook.getContentPane().add(textField);
TextField textField_1 = new TextField();
textField_1.setBounds(457, 87, 254, 22);
frmAddressbook.getContentPane().add(textField_1);
JTextPane txtpnName = new JTextPane();
txtpnName.setText("Name:");
txtpnName.setBounds(437, 46, -87, 20);
frmAddressbook.getContentPane().add(txtpnName);
JLabel lblName = new JLabel("Name :");
lblName.setFont(new Font("DIN 1451 Mittelschrift", Font.PLAIN, 18));
lblName.setBounds(384, 46, 67, 22);
frmAddressbook.getContentPane().add(lblName);
JLabel lblStrae = new JLabel("Straße");
lblStrae.setFont(new Font("DIN 1451 Mittelschrift", Font.PLAIN, 18));
lblStrae.setBounds(384, 87, 67, 22);
frmAddressbook.getContentPane().add(lblStrae);
JLabel lblPlz = new JLabel("PLZ :");
lblPlz.setFont(new Font("DIN 1451 Mittelschrift", Font.PLAIN, 18));
lblPlz.setBounds(384, 141, 67, 22);
frmAddressbook.getContentPane().add(lblPlz);
TextField textField_2 = new TextField();
textField_2.setBounds(457, 141, 59, 22);
frmAddressbook.getContentPane().add(textField_2);
JLabel lblStadt = new JLabel("Stadt :");
lblStadt.setFont(new Font("DIN 1451 Mittelschrift", Font.PLAIN, 18));
lblStadt.setBounds(522, 141, 46, 22);
frmAddressbook.getContentPane().add(lblStadt);
TextField textField_3 = new TextField();
textField_3.setBounds(572, 141, 139, 22);
frmAddressbook.getContentPane().add(textField_3);
/* TODO: Button btnNewAddress zum Anlegen eines neuen Eintrags in der Addressliste
*
* Erzeugen Sie einen JButton btnNewAddress und fügen Sie diesem einen ActionListener
* hinzu, dessen actionPerformed-Methode dem listModel ein neues Address-Element hinzufügt
* mit zunächst irgendwelchen Dummy-Werten für die Adress-Bestandteile.
*
* Behandeln Sie hierbei AddressFormatExceptions derart, dass ein MessageDialog angezeigt wird,
* der die Exception-Message darstellt.
* Tipp: Diesen können Sie mit JOptionPane.showMessageDialog(...) erzeugen.
*/
/* TODO: Erzeugen Sie vier JTextFields und vier JLabels
*
* Die JTextFields und JLabels dienen zur Eingabe der Adressbestandteile
* bzw. zu deren Beschriftung.
*/
/* TODO: Erzeugen Sie eine Speicher-Button btnSave inkl. ActionListener.
*
* In der actionPerformed-Methode des ActionListeners sollen
* 1. die aktuellen Werte der Textfelder in das selektierte Address-Element
* in listModel übertragen werden
* 2. das aktuelle listModel persistent gespeichert werden, wobei
* Exceptions wiederum durch Anzeige von MessageDialogs behandelt werden.
*/
}
public JFrame getFrmAddressbook() {
return frmAddressbook;
}
public void setFrmAddressbook(JFrame frmAddressbook) {
this.frmAddressbook = frmAddressbook;
}
}
-------------------------Neue Java Datei--------------------------------------------
package de.thk.addressbook.persistence;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import de.thk.addressbook.logic.Address;
import de.thk.addressbook.logic.AddressFormatException;
/**
* Eine Implementierung von de.thk.addressbook.persistence.StorageManager.
* Es wird
* @param <T> siehe {@link de.thk.addressbook.persistence.StorageManager}
*/
public class FileStorageManager<T extends Serializable> implements StorageManager<T> {
private String filename;
public FileStorageManager(String filename) {
this.filename = filename;
}
public static void writeToFile(Address a ) throws FileNotFoundException, IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Adresse.bin"));
oos.writeObject(a);
}
/**
* Läd eine Liste aus einer Datei, die bei der Erzeugung dieses
* FileStorageManager-Objekts festgelegt wurde. Falls die Datei nicht
* existiert, wird eine leere Liste (d.h. nicht <code>null</code>)
* zurückgeliefert.
*
* @return Eine ggf. leere Liste
*
* @throws StorageException Wird erzeugt, wenn die Liste nicht geladen werden
* kann. Dies ist insbesondere dann der Fall, wenn auf ein Verzeichnis
* statt auf eine Datei zugegriffen wird oder wenn die Datei nach dem letzten
* Speichern auf ungültige Weise geändert wurde.
*/
@SuppressWarnings("unchecked")
@Override
public List<T> loadOrCreateList() throws StorageException {
/* TODO Ersetzen Sie die Dummy-Implementierung durch ein echtes Laden
* der Datei mit Dateinamen in this.filename
* oder Erzeugen einer leeren Liste.
*/
List<Address> dummyList = new ArrayList<Address>();
try {
dummyList.add(new Address("Dummy-Name", "Dummy-Street", "01234", "Dummy-City"));
} catch (AddressFormatException e) {
e.printStackTrace();
}
return (List<T>)dummyList;
}
/**
* Speichert eine übergebene Liste.
*
* @param list eine ggf. leere Liste, aber nicht <code>null</code>
*
* @throws StorageException Wird erzeugt, wenn Datei nicht gespeichert
* werden kann. Dies ist insbesondere dann der Fall, wenn die Datei
* schreibgeschützt ist.
*/
@Override
public void storeList(List<T> list) throws StorageException {
// TODO Implementieren Sie den Rumpf von storeList
}
}
-------------------------Neue Java Datei--------------------------------------------
package de.thk.addressbook.logic;
import java.util.List;
import de.thk.addressbook.persistence.FileStorageManager;
import de.thk.addressbook.persistence.StorageException;
import de.thk.addressbook.persistence.StorageManager;
/**
* Klasse, die Anwendungslogik implementiert und Klassen / Interfaces
* aus der de.thk.addressbook.persistence verwendet.
*/
public class AddressbookManager {
private StorageManager<Address> storageManager;
/**
* Standard-Konstruktor, in dem festgelegt wird, dass ein dateibasierter
* Storage verwendet wird und die Anwendungsdaten in Datei addressbook.obj
* serialisiert werden.
*/
public AddressbookManager() {
storageManager = new FileStorageManager<Address>("addressbook.obj");
}
/**
* Läd eine Liste aus dem Storage.
* @return Eine ggf. leere Liste (jedoch niemals <code>null</code>)
* @throws StorageException Wird erzeugt, wenn das Laden fehlschlägt.
*/
public List<Address> loadAddresses() throws StorageException {
return storageManager.loadOrCreateList();
}
/**
* Speichert eine übergebene Liste im Storage
* @param addresses Eine ggf. leere Liste (jedoch niemals <code>null</code>)
* @throws StorageException Wird erzeugt, wenn das Speichern fehlschlägt.
*/
public void save(List<Address> addresses) throws StorageException {
storageManager.storeList(addresses);
}
}
-------------------------Neue Java Datei--------------------------------------------
package de.thk.addressbook.logic;
import java.io.Serializable;
/**
* Serialisierbare Domänen-Klasse, die eine Adresse repräsentiert.
*/
public class Address implements Serializable {
private static final long serialVersionUID = 1983140640690682008L;
private String name;
private String street;
private String plz;
private String city;
public Address(String name, String street, String plz, String city) throws AddressFormatException {
setName(name);
setStreet(street);
setPlz(plz);
setCity(city);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getPlz() {
return plz;
}
public void setPlz(String plz) throws AddressFormatException {
// regul�re Ausdr�cke wurden in Vorlesung nicht behandelt
// einfachere Implementierung sind nat�rlich auch erlaubt
if (plz.matches("\\d{5}$")) {
this.plz = plz;
} else {
throw new AddressFormatException("Keine g�ltige PLZ: " + plz);
}
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String toString() {
return name + " | " + street + " | " + plz + " | " + city;
}
}
-------------------------Neue Java Datei--------------------------------------------
package de.thk.addressbook.persistence;
import java.io.Serializable;
import java.util.List;
/**
* Interface, das Methoden zum Speichern von Listen in Storages implementiert.
* Das Interface abstrahiert von des Art des Storages. Implementierungen können
* in Dateien speichern oder aber auch Datenbank-Tabellen etc.
*
* @param <T> Generischer Typparameter, der vom statischen Typ der Listen-Einträge
* (beispielsweise <code>Address</code> abstrahiert.)
*/
public interface StorageManager<T extends Serializable> {
/**
* Wenn eine persistente Liste vorhanden ist, wird diese geladen
* ansonsten eine neue, leere erzeugt.
* @return eine ggf. leere Liste, jedoch niemals <code>null</code>
* @throws StorageException Wird erzeugt, wenn eine vorhandene Liste geladen werden kann.
*/
List<T> loadOrCreateList() throws StorageException;
/**
* Speichert eine übergebene Liste.
* @param list die zu speichernde Liste, die ggf. leer, aber nie null sein darf
* @throws StorageException Wird erzeugt, wenn eine Liste nicht gespeichert werden kann.
*/
void storeList(List<T> list) throws StorageException;
}
-------------------------Neue Java Datei--------------------------------------------
package de.thk.addressbook;
import java.awt.EventQueue;
import de.thk.addressbook.presentation.AddressbookWindow;
/**
* Klasse mit main-Methode zum Starten der Applikation.
*/
public class App {
/**
* Start der Applikation. Die main-Methode wird dabei direkt abgeschlossen.
* Danach wird die run-Methode des in der Event-Queue befindlichen
* Runnable-Objekts ausgeführt.
*
* @param args Kommandozeilenparameter, die hier aber nicht ausgewertet werden.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
AddressbookWindow window = new AddressbookWindow();
window.getFrmAddressbook().setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}